package com.lekang.system.utils;

import java.util.Date;
import java.util.Calendar;
import java.util.List;
import java.util.ArrayList;
import com.lekang.system.domain.TaskArrangement;

/**
 * 任务生成工具类
// * 根据图片中的任务生成逻辑规则实现
 *
 * @author zhihaoViewResolver
 * @date 2025-01-15
 */
public class TaskGenerationUtils {

    /**
     * 生成每日任务
     * 任务生成时间：每日
     * 期望服务时间间隔：(24 - 开始时间) / 执行频次
     * 任务期望服务时间：从"开始时间"开始，然后是"开始时间 + 间隔"，接着是"第二段时间 + 间隔"，以此类推
     *
     * @param elderlyId 老人ID
     * @param nursingItemId 护理项目ID
     * @param executionFrequency 执行频次
     * @param plannedStartTime 计划执行开始时间
     * @param projectType 项目类型
     * @return 任务列表
     */
    public static List<TaskArrangement> generateDailyTasks(Long elderlyId, Long nursingItemId,
                                                         Integer executionFrequency, Date plannedStartTime,
                                                         String projectType) {
        List<TaskArrangement> tasks = new ArrayList<>();
        Calendar cal = Calendar.getInstance();
        cal.setTime(plannedStartTime);

        // 计算时间间隔：(24 - 开始时间) / 执行频次
        int startHour = cal.get(Calendar.HOUR_OF_DAY);
        int interval = (24 - startHour) / executionFrequency;

        for (int i = 0; i < executionFrequency; i++) {
            TaskArrangement task = new TaskArrangement();
            task.setElderlyId(elderlyId);
            task.setProjectNameId(nursingItemId);
            task.setProjectType(projectType);
            task.setStatus("待执行");
            task.setCreateTime(new Date());

            // 计算期望服务时间
            Calendar taskCal = Calendar.getInstance();
            taskCal.setTime(plannedStartTime);
            taskCal.add(Calendar.HOUR_OF_DAY, i * interval);
            task.setExpectedServiceTime(taskCal.getTime());

            tasks.add(task);
        }

        return tasks;
    }

    /**
     * 生成每周任务
     * 任务生成日期间隔：7天 / 执行频次
     * 任务生成日期：从星期一（星期1）开始，然后是"星期1 + 间隔"，接着是"星期2 + 间隔"，以此类推
     * 期望服务时间：等于计划执行开始时间
     *
     * @param elderlyId 老人ID
     * @param nursingItemId 护理项目ID
     * @param executionFrequency 执行频次
     * @param plannedStartTime 计划执行开始时间
     * @param projectType 项目类型
     * @return 任务列表
     */
    public static List<TaskArrangement> generateWeeklyTasks(Long elderlyId, Long nursingItemId,
                                                           Integer executionFrequency, Date plannedStartTime,
                                                           String projectType) {
        List<TaskArrangement> tasks = new ArrayList<>();
        Calendar cal = Calendar.getInstance();
        cal.setTime(plannedStartTime);

        // 计算日期间隔：7天 / 执行频次
        int dayInterval = 7 / executionFrequency;

        for (int i = 0; i < executionFrequency; i++) {
            TaskArrangement task = new TaskArrangement();
            task.setElderlyId(elderlyId);
            task.setProjectNameId(nursingItemId);
            task.setProjectType(projectType);
            task.setStatus("待执行");
            task.setCreateTime(new Date());

            // 计算期望服务时间
            Calendar taskCal = Calendar.getInstance();
            taskCal.setTime(plannedStartTime);
            taskCal.add(Calendar.DAY_OF_MONTH, i * dayInterval);
            task.setExpectedServiceTime(taskCal.getTime());

            tasks.add(task);
        }

        return tasks;
    }

    /**
     * 生成每月任务
     * 任务生成日期间隔：30天 / 执行频次
     * 任务生成日期：从1号开始，然后是"1号 + 间隔"，接着是"第二个日期 + 间隔"，以此类推
     * 期望服务时间：等于计划执行开始时间
     *
     * @param elderlyId 老人ID
     * @param nursingItemId 护理项目ID
     * @param executionFrequency 执行频次
     * @param plannedStartTime 计划执行开始时间
     * @param projectType 项目类型
     * @return 任务列表
     */
    public static List<TaskArrangement> generateMonthlyTasks(Long elderlyId, Long nursingItemId,
                                                            Integer executionFrequency, Date plannedStartTime,
                                                            String projectType) {
        List<TaskArrangement> tasks = new ArrayList<>();
        Calendar cal = Calendar.getInstance();
        cal.setTime(plannedStartTime);

        // 计算日期间隔：30天 / 执行频次
        int dayInterval = 30 / executionFrequency;

        for (int i = 0; i < executionFrequency; i++) {
            TaskArrangement task = new TaskArrangement();
            task.setElderlyId(elderlyId);
            task.setProjectNameId(nursingItemId);
            task.setProjectType(projectType);
            task.setStatus("待执行");
            task.setCreateTime(new Date());

            // 计算期望服务时间
            Calendar taskCal = Calendar.getInstance();
            taskCal.setTime(plannedStartTime);
            taskCal.add(Calendar.DAY_OF_MONTH, i * dayInterval);
            task.setExpectedServiceTime(taskCal.getTime());

            tasks.add(task);
        }

        return tasks;
    }

    /**
     * 根据执行周期类型生成任务
     *
     * @param elderlyId 老人ID
     * @param nursingItemId 护理项目ID
     * @param executionCycleType 执行周期类型（每日、每周、每月）
     * @param executionFrequency 执行频次
     * @param plannedStartTime 计划执行开始时间
     * @param projectType 项目类型
     * @return 任务列表
     */
    public static List<TaskArrangement> generateTasksByCycle(Long elderlyId, Long nursingItemId,
                                                            String executionCycleType, Integer executionFrequency,
                                                            Date plannedStartTime, String projectType) {
        switch (executionCycleType) {
            case "每日":
                return generateDailyTasks(elderlyId, nursingItemId, executionFrequency, plannedStartTime, projectType);
            case "每周":
                return generateWeeklyTasks(elderlyId, nursingItemId, executionFrequency, plannedStartTime, projectType);
            case "每月":
                return generateMonthlyTasks(elderlyId, nursingItemId, executionFrequency, plannedStartTime, projectType);
            default:
                throw new IllegalArgumentException("不支持的执行周期类型: " + executionCycleType);
        }
    }

    /**
     * 生成护理计划内任务
     * 根据图片说明：
     * - 入住首月：当入住完成后，生成首月账单后生成护理任务
     * - 非首月：每个月1号00:00:00生成任务
     * - 每日00:00时，刷新所有未执行的任务，若该老人已退住成功，则不再显示该老人待执行的任务
     *
     * @param elderlyId 老人ID
     * @param nursingItemId 护理项目ID
     * @param executionCycleType 执行周期类型
     * @param executionFrequency 执行频次
     * @param plannedStartTime 计划执行开始时间
     * @return 任务列表
     */
    public static List<TaskArrangement> generateNursingPlanTasks(Long elderlyId, Long nursingItemId,
                                                               String executionCycleType, Integer executionFrequency,
                                                               Date plannedStartTime) {
        return generateTasksByCycle(elderlyId, nursingItemId, executionCycleType, executionFrequency,
                                   plannedStartTime, "护理计划内");
    }

    /**
     * 生成护理计划外任务
     * 根据图片说明：用户端下单且支付成功的订单生成的任务
     *
     * @param elderlyId 老人ID
     * @param nursingItemId 护理项目ID
     * @param expectedServiceTime 期望服务时间
     * @param creator 创建人（下单用户昵称）
     * @param creatorId 创建人ID
     * @param orderNo 订单号
     * @return 任务
     */
    public static TaskArrangement generateNonNursingPlanTask(Long elderlyId, Long nursingItemId,
                                                           Date expectedServiceTime, String creator,
                                                           Long creatorId, String orderNo) {
        TaskArrangement task = new TaskArrangement();
        task.setElderlyId(elderlyId);
        task.setProjectNameId(nursingItemId);
        task.setProjectType("护理计划外");
        task.setExpectedServiceTime(expectedServiceTime);
        task.setStatus("待执行");
        task.setCreateTime(new Date());
        task.setRelatedOrderNo(orderNo);

        return task;
    }
}
